<template>
  <div class="ai-picture-handle">
    <Modal
      v-model="visible"
      title="上传和编辑图片"
      :width="1000"
      :mask-closable="false"
      :ok-text="'发送'"
      @on-ok="sendFormData()"
      @on-visible-change="watchModelStatus">
  <div class="ai-picture-handle">
    <Upload
      :before-upload="beforeUpload"
      accept="image/png"
      ref="upload"
      action="()=>"
    >
      <Button type="primary" icon="ios-cloud-upload-outline">选择文件</Button>
    </Upload>

    <canvas
      ref="canvas"
      @dblclick="edit"
      :width="canvasWidth"
      :height="canvasHeight"
      class="image-canvas"
      />

    <div class="btn-group" v-show="editing">
      <Button class="zoom-in" @click="zoomIn" icon="ios-add-circle-outline">放大</Button>
      <Button class="zoom-out" @click="zoomOut" icon="ios-remove-circle-outline">缩小</Button>
      <Button class="save" @click="save" icon="ios-checkmark-circle-outline">保存</Button>
    </div>
    <RadioGroup v-model="picModel">
      <Radio v-if="dynamicModelShow" label="0">图片动态联想</Radio>
      <Radio label="1">有截取原图相关性</Radio>
      <Radio label="2">无截取原图相关性</Radio>
    </RadioGroup>
    <Input v-model="prompt" type="textarea" placeholder="请输入图片生成相关描述" />
  </div>
    </Modal>
  </div>
</template>

<script>
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class AiPictureHandle extends Vue {

  visible = true;
  drawing = false
  rect = { startX: 0, startY: 0, endX: 0, endY: 0 }
  img = new Image()
  scale = 0.3
  editing =false
  originalSize = { width: 0, height: 0 }
  rectangle = null
  saved = false
  picModel = '0'
  prompt = ''
  dynamicModelShow = true
  aiPictureHandleFromData = null
  picOriginal = null;

  mounted() {

    const canvas = this.$refs.canvas;
    const ctx = canvas.getContext('2d');

    canvas.addEventListener('mousedown', (e) => {
      if (!this.editing) return;
      this.drawing = true;
      this.rect.startX = e.clientX - canvas.getBoundingClientRect().left;
      this.rect.startY = e.clientY - canvas.getBoundingClientRect().top;
    });

    canvas.addEventListener('mousemove', (e) => {
      if (!this.drawing || !this.editing) return;
      this.rect.endX = e.clientX - canvas.getBoundingClientRect().left;
      this.rect.endY = e.clientY - canvas.getBoundingClientRect().top;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(this.img, 0, 0, canvas.width, canvas.height);
      ctx.strokeStyle = 'red';
      ctx.lineWidth = 2;
      ctx.strokeRect(this.rect.startX, this.rect.startY, this.rect.endX - this.rect.startX, this.rect.endY - this.rect.startY);
    });

    canvas.addEventListener('mouseup', () => {
      if (this.editing) {
        this.rectangle ={
          startX: this.rect.startX / this.scale,
          startY: this.rect.startY / this.scale,
          endX: this.rect.endX / this.scale,
          endY: this.rect.endY / this.scale
        };
      }
      this.drawing = false;
    });

    canvas.addEventListener('mouseout', () => {
      this.drawing = false;
    });

    this.img.onload = () => {
      this.originalSize.width = this.img.width;
      this.originalSize.height = this.img.height;
      this.resizeCanvas();
      this.drawImage();
    };
  }
  zoomIn() {
    this.scale += 0.1;
    this.resizeCanvas();
  }
  zoomOut() {
    if (this.scale > 0.1) {
      this.scale -= 0.1;
      this.resizeCanvas();
    }
  }
  save() {
    this.editing = false;
    this.saved = true;

    const startX = this.rectangle.startX * this.scale;
    const startY = this.rectangle.startY * this.scale;
    const width = (this.rectangle.endX - this.rectangle.startX) * this.scale;
    const height = (this.rectangle.endY - this.rectangle.startY) * this.scale;
    //  如果有在图片上画矩形，那么默认图片模式是截图有关联性的
    if ( startX != 0 || startY != 0 || width != 0 || height != 0 ) {
      this.picModel = '1'
      this.dynamicModelShow = false
    }

    this.rectangle = {startX:startX,startY:startY,width:width,height: height }

    // 保存画好的矩形区域
    const canvas = this.$refs.canvas.cloneNode(true);
    const ctx = canvas.getContext('2d');
    ctx.drawImage(this.img.cloneNode(true), 0, 0, canvas.width, canvas.height); // 绘制图片

    //  整合编辑图像等相关数据
    const canvasOrg = canvas.cloneNode(true);
    const ctxOrg = canvasOrg.getContext('2d');
    ctxOrg.drawImage(this.img.cloneNode(true), 0, 0, canvas.width, canvas.height); // 绘制图片
    canvasOrg.toBlob((blob) => {
      // 将 Blob 对象添加到 FormData 对象
      const formData = new FormData();
      formData.append('image', blob, 'canvas-image.png');
      // 将 rectangle 数据添加到 FormData 对象
      formData.append('rectangle', JSON.stringify(this.rectangle));
      // 将 picModel 和 prompt 数据添加到 FormData 对象
      formData.append('picModel', this.picModel);

      this.aiPictureHandleFromData = {
        croppedImageDataUrl: croppedImageDataUrl,
        sendFormData: formData,
        prompt: ''
      }
    });

    ctx.strokeStyle = 'red';
    ctx.lineWidth = 2;
    ctx.strokeRect(startX, startY, width, height); // 绘制矩形

    const croppedImageDataUrl = canvas.toDataURL();


  }
  edit() {
    if (!this.editing) {
      this.rectangle = null;
      this.editing = true;
      this.rectangle = {};
    }
  }

  resizeCanvas() {
    this.rectangle = null;
    const canvas = this.$refs.canvas;
    canvas.width = this.originalSize.width * this.scale;
    canvas.height = this.originalSize.height * this.scale;
    this.img.onload = () => {
      this.drawImage();
    };
    this.img.src = this.img.src; // 重新设置图片源，触发 onload 事件
  }
  // 添加计算属性
  get canvasWidth() {
    return this.img.width * this.scale;
  }

  get canvasHeight() {
    return this.img.height * this.scale;
  }

  // 在上传之前检查文件
  beforeUpload(file) {

    if (file.size > 4 * 1024 * 1024) {
      this.$Message.error('上传的图片大小不能超过 4M');
      return false;
    }

    if (file.type !== 'image/png') {
      this.$Message.error('只支持上传 png 格式的图片');
      return false;
    }

    const reader = new FileReader();

    reader.onload = (e) => {
      this.img.src = e.target.result;
      this.img.onload = () => {
        this.originalSize.width = this.img.width;
        this.originalSize.height = this.img.height;
        this.resizeCanvas();
        this.drawImage();
      };
    };
    reader.readAsDataURL(file);
    this.picOriginal = file;
    // 返回 false 取消自动上传
    return false;
  }
  drawImage() {
    const canvas = this.$refs.canvas;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(this.img, 0, 0, canvas.width, canvas.height);
  }
  watchModelStatus(status){
    if ( !status ) {
      this.$emit('modalClose', null)
    }

  }

  async asyncSendFormData() {
    let thisObj = this;

    return new Promise(async (resolve, reject) => {
      if (thisObj.aiPictureHandleFromData != null) {
        thisObj.aiPictureHandleFromData.prompt = thisObj.prompt;
        thisObj.aiPictureHandleFromData.sendFormData.append('prompt', thisObj.prompt);
        thisObj.aiPictureHandleFromData.sendFormData.set('picModel', thisObj.picModel);
        resolve(thisObj.aiPictureHandleFromData);
        return;
      }

      if (thisObj.picOriginal != null) {
        const croppedImageDataUrl = await new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = (e) => {
            resolve(e.target.result);
          };
          reader.onerror = (e) => {
            reject(e);
          };
          reader.readAsDataURL(thisObj.picOriginal);
        });

        const formData = new FormData();
        formData.append('image', thisObj.picOriginal, 'canvas-image.png');
        formData.append('picModel', thisObj.picModel);

        thisObj.aiPictureHandleFromData = {
          croppedImageDataUrl: croppedImageDataUrl,
          sendFormData: formData,
          prompt: thisObj.prompt
        };
        resolve(thisObj.aiPictureHandleFromData);
        return;
      }
      resolve(null);
    });
  }

   sendFormData() {
     this.$emit('sendFormData', this.asyncSendFormData());
   }
}
</script>

<style scoped>
.ai-picture-handle {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.image-canvas {
  margin-top: 20px;
  border: 1px solid #dcdfe6;
}

.btn-group {
  margin-top: 20px;
}

.btn-group .ivu-btn {
  margin-right: 10px;
}
</style>
